package com.test.common.entity.system;

import com.test.common.entity.auto.TestProductEntity;
import com.test.common.entity.perf.PerfTaskEntity;
import com.test.common.enums.system.PermissionLevelEnum;
import com.test.common.enums.system.PermissionTargetEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.Permission;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Slf4j
@Data
@Entity
@Table(name = "t_permission")
public class PermissionImpl implements Permission {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@Enumerated(EnumType.STRING)
	private PermissionLevelEnum permission = PermissionLevelEnum.READ;

	private int targetId;

	@Enumerated(EnumType.STRING)
	private PermissionTargetEnum targetType;

	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "t_role_permission", joinColumns = {
			@JoinColumn(name = "permissionId", referencedColumnName = "id")}, inverseJoinColumns = {
			@JoinColumn(name = "roleId", referencedColumnName = "id")})
	private Set<Role> permissions = new HashSet<>();

	public PermissionImpl() {
	}

	public PermissionImpl(PermissionLevelEnum permission) {
		this.permission = permission;
	}

	public PermissionImpl(PermissionLevelEnum permission, TestProductEntity testProductEntity) {
		this.permission = permission;
		this.targetId = testProductEntity.getId();
		this.targetType = PermissionTargetEnum.AUTH_PROD;
	}

	public PermissionImpl(PermissionLevelEnum permission, PerfTaskEntity perfTaskEntity) {
		this.permission = permission;
		this.targetId = perfTaskEntity.getId();
		this.targetType = PermissionTargetEnum.PERF_TASK;
	}

	public PermissionImpl(int targetId, PermissionTargetEnum targetType, PermissionLevelEnum permission) {
		this.permission = permission;
		this.targetType = targetType;
		this.targetId = targetId;
	}

	@Override
	public boolean implies(Permission p) {
		PermissionImpl permission1 = (PermissionImpl) p;
		return permission1.targetId == this.targetId && permission1.targetType == this.targetType && this.permission.compareTo(permission1.getPermission()) >= 0;
	}
}
